#-*-coding:utf8-*-

"""puits ---> Ce module contient une classe qui s’appelle Puits """

from time import time, sleep
from random import *
from donnees import *
from imagerie import *
from fonction import Arbre_Donne_Etat, Energie_Capteur, Energie_Agregateur, Quelle_Categorie, Comparer_Des_Decision, Voisin
from distance import *
from sklearn import svm


class Puits: 

   """ Cette classe contient les méthodes __init__ () et run() """

   def __init__(self, Foret = None, Svm = None, Sgd = None, Gnb = None, Tbfs = None, Mma = None):

       """ __init__(foret) ---> cette méthode permet initialiser l'objet de type Puits """

       self.x, self.y = POSITION_PUITS 
       self.Foret = Foret
       self.Svm = Svm
       self.Sgd = Sgd
       self.Gnb = Gnb
       self.Tbfs = Tbfs
       self.Mma = Mma
       assert 0<=self.x <= 1
       assert 0<=self.y <= 1        
       self.valeursRecues = []
       self.valeurs = []
       self.agregateurs = []
       self.dicoCapteurs = {}
       self.lesPuits = []

       if CHIFFREMENT:
           print("On doit chiffrer les données sur le réseau")
           if fichierCles == None:
               print "Création des clés de chiffrement"
               print("Taille des clés : "+str(tailleCles))
               print("Génération des clés de "+str(tailleCles)+" bits")
               self.resume.write("Taille des clés : "+str(tailleCles)+'\n')
               (self.Kp,self.Ks) = rsa.newkeys(tailleCles)
               if SAUVEGARDE_CLES:
                   fichier = raw_input("Quel nom de fichier de clé ?")
                   dd = open('data/'+fichier,'wb')
                   dump((self.Kp,self.Ks),dd)
                   dd.close()
           else:
               ee = open(fichierCles,'rb')
               (self.Kp,self.Ks) = load(ee)
               self.resume.write("Fichier des clés : " + fichierCles+'\n')
    
           print("Les Clés publiques : "+str(self.Kp))
           print("Les Clés secretes : "+str(self.Ks))
           print("Génération finie")
       if videoRealite :
           print "-> On trace ce qui se passe réellement, dans videoRealite.avi"
           Trace_Fonction(f)

       # On lance le tout
       self.BigBang = time()
        
        
    
   def Run(self):

       """ Run() ---> cette méthode permet de démarrer le travail du réseaux, il boucle TEMPS_SIMULATION fois et chaque fois boucle TEMPS_ECOUTE fois,
       Si la Topologie est égale à 1 : pour chaque boucle, tous les capteurs captent les données et les envoient à leur agrégateur, et les agrégateurs envoient les données agrégées à l’agrégateur cible (qui peut être le puits ou un autre agrégateur) et dessine la topologie.
       Si la Topologie est égale à 2 :  pour chaque boucle, tous les capteurs captent les données et les envoient à leur capteur cible, et les capteurs cibles renvoient les donnes reçus à leur capteur cible (qui peut être puits ou un autre capteur ) et dessine la topologie. Ensuite nous utilisons les Forêts aléatoires pour prendre la décision.
       Enfin nous représentons les données reçues par le puits par une graphe 3d (la position des capteurs en fonction des données envoyées)  """ 

     
       print("LE PUITS DEMARRE LE TRAVAIL")

       global heure
       
       if not SIR :

           EnergieCapteur = []
           MortCapteur = []
           MortAgregateur = []
           EnergieAgregateur = []
           CapteursDetectentPanne = []
           MemoireC = []
           Transferer = []
           MemoireA = []

           Decision_Foret = []
           Decision_SVM = []
           
           Decision_F = []            
           Decision_S = []

           Decision_Reel_Foret = []
           Decision_R_F = []

           Decision_Reel_SVM = []           
           Decision_R_V = []

           Accuracy_Foret = []
           Erreur_Foret = []

           Accuracy_SVM = []
           Erreur_SVM = []

           Decision_Reel_SGD = []
           Decision_R_G = []
           Decision_SGD = []
           Decision_G = []       
           Accuracy_SGD = []
           Erreur_SGD = []

           Decision_Reel_GNB = []
           Decision_R_N = []
           Decision_GNB = []
           Decision_N = []       
           Accuracy_GNB = []
           Erreur_GNB = []

           Decision_Reel_TBFS = []
           Decision_R_T = []
           Decision_TBFS = []
           Decision_T = []           
           Accuracy_TBFS = []
           Erreur_TBFS = []

           Decision_Reel_MMA = []
           Decision_R_M = []
           Decision_MMA = []
           Decision_M = []           
           Accuracy_MMA = []
           Erreur_MMA = []

           F =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 24]
           p = 1

           for NB in F:

               if FORET :
                   print "SIMULATION AVEC NOMBRE DE FORET EST: {}".format(NB)
                   
               if SVM or SGD or GNB or TBFS or MMA:
                   print "SIMULATION NUMERO {} ".format(p) 
                   p += 1

               sleep(1)

               for nombre_simulation in range(NOMBRE_SIMULATION) :

                   print "C'est le {}ème SIMULATION".format(nombre_simulation)
                     

                   for cc in self.dicoCapteurs.values() :
                       cc.energie = BatterieCapteurs
                       cc.mort = False
                       cc.capteursDetectentPanne = False                   
                       cc.memoire = []

                   for a, aa in enumerate(self.agregateurs) :
                       aa.energie = BatterieAgregateurs 
                       aa.mort = False
                       aa.aTransferer = []
                       for i in Categ.keys() :
                           aa.memoire[i] = []

                   heure = 0
                   temps_simulation = 0

           
                   while temps_simulation < TEMPS_SIMULATION :
           
                       for cc in self.dicoCapteurs.values() :
                           EnergieCapteur.append(cc.energie)
                           MortCapteur.append(cc.mort)
                           CapteursDetectentPanne.append(cc.capteursDetectentPanne)
                           if Topologie == 2:
                               MemoireC.append(cc.memoire)
 
                       for a, aa in enumerate(self.agregateurs) :
                           EnergieAgregateur.append(aa.energie)  
                           MortAgregateur.append(aa.mort)
                           Transferer.append(aa.aTransferer) 
                           MemoireA.append(aa.memoire)

                       h = heure

                       # L'utilisateur précise le TEMPS_SIMULATION du réseau
                       print ("Durée écoulée de simulation "+str(nombre_simulation)+" est : "+str(temps_simulation))


                       # L'utilisateur précise le TEMPS_ECOUTE du réseau
                       print "Le TEMPS_ECOUTE est  : {} ".format(TEMPS_ECOUTE)

               
                
                       ligne = {}
        
                       for temps in range(TEMPS_ECOUTE):

                           if Topologie == 1:
          
                               # Production d'infos
                               print "    -> Agrégateurs restants :", len([ag for ag in self.agregateurs if not ag.mort])
                               print("Durée écoulée : "+str(temps)+" secondes")
                  
                 
                               # Les capteurs envoient aux agrégateurs
                               for ag in self.agregateurs:
                                   if not ag.mort:
                                       # Les capteurs ont leur énergie qui décroit naturellement
                                       for cap in [capt for capt in ag.capteurs if not capt.mort]:
                                           cap.energie -= coutEcouteCapteurs

                                           if cap.energie < 0:
                                               cap.mort = True
                                   

                                           else :
                                               for i in Categ.keys():
                             
                                                   if cap.Categorie == i:
                                                       # Le capteur relève alors une valeur
                                                       t=time()

                                                       if eval(loiPanne) >= 1:
                                                            cap.valeur = Categories[i]["erreurCapteur"]

                                                       elif cap.capteursDetectentPanne == False:
                                                           cap.valeur = eval(Categories[i]["loi"])
                                            
                                                           if eval(loiPanne) >= 1:
                                                               cap.capteursDetectentPanne = True 
                                                       else:
                                                           cap.valeur = eval(Categories[i]["loiPanne"])

                                                       # On chiffre éventuellement la donnée
                                                       if CHIFFREMENT:
                                                           cap.cr = rsa.encrypt(str(cap.valeur), cap.Kp)
                                                       else:
                                        
                                                           cap.cr = cap.valeur


                                                       # On décrémente l'énergie du capteur du coût de transmission à l'agrégateur

                                                       # indice = 1 si le capteur capter le donnée et l'envoie a l'agregateur ou capteur cible si Topologie = 2
                                                       # indice = 2 si le capteur envoie les données au capteur cible (dans cas si Topologie = 2)

                                                       cap.energie -= Energie_Capteur(capteur = cap, cible = cap.agregateur, indice = 1, temps = t) 
                                      
                                                       if cap.energie > 0:
                                                           # Si le coût de transmission est inférieur à l'énergie restante, on envoie
                                                           # effectivement la donnée à l'agrégateur
                                                           cap.agregateur.memoire[i].append(cap.cr)
                                                           cap.sir = []
                                                       else:
                                                           # Le capteur meurt s'il n'a plus d'énergie
                                                           print "   -> Mort du capteur", cap.numero, "de l'agrégateur", ag.numero
                                                           cap.mort = True  
                                                   else:
                                                       pass
                   
        
                               heure += 100./individus 

                               # Les agrégateurs envoient aux agrégateurs, ou puits, si leur mémoire est saturée.            
                               for ag in self.agregateurs :
                                   if not ag.mort:
                                       if ag.aTransferer != [] :
                                           # Si un agrégateur doit transférer des données, il commence par le faire
                                           # Décrémenter l’énergie et tester avant d'envoyer à l’agrégateur cible
                                           print("   -> L'agrégateur n°" + str(ag.numero) + " doit transférer : " + str(ag.aTransferer))
                            
                                           if ag.agregateurCible != self and not ag.agregateurCible.mort:

                                               # indice = 1 : si l'agregateur agreger les données apres anvoyer a l'agregateur cible
                                               # indice = 2 : si l'agregateur va envoyer les données a l'agregateur cible

                                               ag.energie -= Energie_Agregateur(agregateur = ag ,agregateurCible = ag.agregateurCible, indice = 2)
                               
                                               if ag.energie > 0:
                                                   ag.agregateurCible.aTransferer.extend(ag.aTransferer)
                                                   ag.aTransferer = []
                                               else:
                                                   ag.mort = True 
                                           elif  ag.agregateurCible == self :
                                               # indice = 1 : si l'agregateur va envoyer les données a l'agregateur cible
                                               # indice = 2 : si l'agregateur agreger les données apres anvoyer a l'agregateur cible

                                               ag.energie -= Energie_Agregateur(agregateur = ag ,agregateurCible = ag.agregateurCible, indice = 2)
                                
                                               if ag.energie > 0:
                                                   self.valeursRecues.extend(ag.aTransferer) 
                                                   ag.aTransferer = []    
                                               else:
                                                   ag.mort = True 

                                                    
                 

                                           # Si la mémoire de l'égrégateur est pleine, on doit transférer les données 
                                           # après agrégation

                                       # agreger les donnees de capteurs

                                       for j  in Categ.keys():
                        
                                           while len(ag.memoire[j]) >= MemoireAgregateurs and not ag.mort:
                                               print("   -> L'Agrégateur n°" + str(ag.numero) + " agrège ")
                                               somme = 0
                                               u = time()
                                               for kk in range(MemoireAgregateurs):
                                                   cr = ag.memoire[j][kk]   
                                                   # Les données peuvent être chiffrées : il faut les déchiffrer
                                                   if CHIFFREMENT:
                                                       valeur = int(rsa.decrypt(cr, ag.Ks))
                                                   else :
                                                       valeur = cr
                                                   somme += valeur   
                                               # La somme obtenue par agrégation doit peut-être être chiffrée 
                                               if CHIFFREMENT:
                                                   cr = rsa.encrypt(str(somme), ag.Kp)  
                                               else:
                                                   cr = str(somme)  
                    
                                               # Soit on envoie directement la somme (event. chiffrée) au puits, soit
                                               # on la transfert à son agrégateur cible  
                                               if DIRECT_AGREGATEUR_PUITS:
                                                   # indice = 1 : si l'agregateur agreger les données apres anvoyer a l'agregateur cible
                                                   # indice = 2 : si l'agregateur va envoyer les données a l'agregateur cible
                                                   sleep(0.2)
                                                   ag.energie -= Energie_Agregateur(agregateur = ag ,agregateurCible = self, indice = 1, temps = u)
                                    
                                                   if ag.energie > 0:
                                                       self.valeursRecues.extend([[(ag.x, ag.y, time()-self.BigBang), j, cr]])       
                                                   else:
                                                       ag.mort = True 
                                               else:

                                                   if ag.agregateurCible == self:

                                                       # indice = 1 : si l'agregateur agreger les données apres anvoyer a l'agregateur cible
                                                       # indice = 2 : si l'agregateur va envoyer les données a l'agregateur cible

                                                       ag.energie -= Energie_Agregateur(agregateur = ag ,agregateurCible = ag.agregateurCible, indice = 1, temps = u)
                                        
                                                       if ag.energie > 0:
                                                           self.valeursRecues.extend([[(ag.x, ag.y, time()-self.BigBang), j, cr]]) 
                                                       else:
                                                           ag.mort = True
                                                   elif not ag.agregateurCible.mort: 
 
                                                       # indice = 1 : si l'agregateur agreger les données apres anvoyer a l'agregateur cible
                                                       # indice = 2 : si l'agregateur va envoyer les données a l'agregateur cible

 
                                                       ag.energie -= Energie_Agregateur(agregateur = ag ,agregateurCible = ag.agregateurCible, indice = 1, temps = u)
                                        
                                                       if ag.energie > 0:
                                                           ag.agregateurCible.aTransferer.append([(ag.x, ag.y, time()-self.BigBang), j, cr]) 
                                                       else:
                                                           ag.mort = True       
                               
                                       
                                               # Enlever de la mémoire les données agrégées  
                                               del ag.memoire[j][:MemoireAgregateurs]  
                                           

               

                                       else:
                                           # L'agrégateur est vivant et sa mémoire n'est pas pleine, il ne fait donc rien
                                           pass

                                       # L'énergie des agrégateurs décroît naturellement
                                       ag.energie -= coutEcouteAgregateurs
                                       if ag.energie < 0:
                                           ag.mort = True

                               if temps_simulation == 0 and temps == 0:

                                   if Topologie == 1:
                                       Trace_Topologie_1(self, "Initiale") 
 
                                   elif Topologie == 2:
                                       Trace_Topologie_2(self, "Initiale")
                       
                           elif Topologie == 2:

                               print "    -> Capteurs restants :", len([c for c in self.dicoCapteurs.values() if not c.mort])
                               print("Durée écoulée : " + str(temps) + " secondes")
                                     
                               # Les capteurs envoient Capteur Cible
                               for cpt in self.dicoCapteurs.values() :
                                   if not cpt.mort:
                                       # Les capteurs ont leur énergie qui décroit naturellement 
                                       cpt.energie -= coutEcouteCapteurs
                                       if cpt.energie < 0:
                                           cpt.mort = True
                          
                        
                                       else:
                                           for i in Categ.keys():
                             
                               
                                               if cpt.Categorie == i: 

                                                   if cpt.memoire != [] :
                                                       # Si un capteur doit transférer des données, il commence par le faire
                                                       # Décrémenter l’énergie et tester avant d'envoyer à la Capteur cible
                                                       print("   -> Le capreur n°"+str(cpt.numero)+" doit transférer : "+str(cpt.memoire))

                                                       if cpt.capteurCible != self and not cpt.capteurCible.mort:

                                                           # indice = 1 si le capteur capter le donnée et l'envoie a l'agregateur ou capteur cible si Topologie = 2
                                                           # indice = 2 si le capteur envoie les données au capteur cible (dans cas si Topologie = 2)

                                                           cpt.energie -= Energie_Capteur(capteur = cpt, cible = cpt.capteurCible, indice = 2) 
                                            

                                                           if cpt.energie > 0:
                                                           # Tester si le capteur cible est toujours vivant avant d'envoyer les données
                                                               cpt.capteurCible.memoire.extend(cpt.memoire)
                                                               cpt.memoire = [] 
                                                           else:
                                                               cpt.mort = True

                                                       elif cpt.capteurCible == self  :
                        
                                                           # indice = 1 si le capteur capter le donnée et l'envoie a l'agregateur ou capteur cible si Topologie = 2
                                                           # indice = 2 si le capteur envoie les données au capteur cible (dans cas si Topologie = 2)
                                          
                                                           cpt.energie -= Energie_Capteur(capteur = cpt, cible = self, indice = 2) 
                                            
                                                           if cpt.energie > 0:
                                                               self.valeursRecues.extend(cpt.memoire)
                                                               cpt.memoire = [] 
                                                           else :
                                                               cpt.mort = True 
                             
                                                 
                                                   if not  cpt.mort :
                                                       # Le capteur relève alors une valeur
                                                       t = time()

                                                       if eval(loiPanne) >= 1:
                                                           cpt.valeur = Categories[i]["erreurCapteur"]

                                                       elif cpt.capteursDetectentPanne == False:
                                                           cpt.valeur=eval(Categories[i]["loi"])
                                            
                                                           if eval(loiPanne) >= 1:
                                                               cpt.capteursDetectentPanne = True 
                                                       else:
                                                           cpt.valeur = eval(Categories[i]["loiPanne"])

                                                       # On chiffre éventuellement la donnée
                                                       if CHIFFREMENT:
                                                           cpt.cr = rsa.encrypt(str(cap.valeur), cpt.Kp)
                                                       else:     
                                                           cpt.cr = str(cpt.valeur)

                                              
                                                       # On envoie directement à son Capteur Cible
                                                       # On décrémente l'énergie du capteur du coût de transmission à son Capteur Cible
                                                       if cpt.capteurCible == self:

                                                           # indice = 1 si le capteur capter le donnée et l'envoie a l'agregateur ou capteur cible si Topologie = 2
                                                           # indice = 2 si le capteur envoie les données au capteur cible (dans cas si Topologie = 2)

                                                           cpt.energie -= Energie_Capteur(capteur = cpt, cible = self, indice = 1, temps = t)
                                       
                                                           # Si le coût de transmission est inférieur à l'énergie restante, on envoie
                                                           if cpt.energie > 0:
                                                               self.valeursRecues.extend([[(cpt.x, cpt.y, time()-self.BigBang), i, cpt.cr]]) 
                                                           else:
                                                               cpt.mort = True

                                                       elif not cpt.capteurCible.mort :

                                                           # indice = 1 si le capteur capter le donnée et l'envoie a l'agregateur ou capteur cible si Topologie = 2
                                                           # indice = 2 si le capteur envoie les données au capteur cible (dans cas si Topologie = 2) 
                                       
                                                           cpt.energie -= Energie_Capteur(capteur = cpt, cible = cpt.capteurCible, indice = 1, temps = t) 
                                        
                                                           # Si le coût de transmission est inférieur à l'énergie restante, on envoie 
                                                           if cpt.energie > 0:
                                                               cpt.capteurCible.memoire.append([(cpt.x, cpt.y, time()-self.BigBang), i, cpt.cr])
                                                           else:
                                                               cpt.mort = True
                                   
                               heure += 100./individus 

                               if temps_simulation == 0 and temps == 0:

                                   if Topologie == 1:
                                       Trace_Topologie_1(self, "Initiale") 
 
                                   elif Topologie == 2:
                                       Trace_Topologie_2(self, "Initiale")
                       
                       if Topologie == 1:
                           Trace_Topologie_1(self, str(nombre_simulation)+"_"+str(temps_simulation).zfill(10)) 
 
                       elif Topologie == 2:
                           Trace_Topologie_2(self, str(nombre_simulation)+"_"+str(temps_simulation).zfill(10)) 
      
                       for ty in Categories.keys():
                           ligne[ty] = []  
           
                           for i in self.valeursRecues :
                               if i[1] == ty:
                                   if Topologie == 1:
                                       ligne[ty].append(eval(i[2])/MemoireAgregateurs)
                                   elif Topologie == 2:
                                       ligne[ty].append(eval(i[2]))
       
 
       

                       for test in ligne.keys():
                           if ligne[test] == []:
                               ligne[test].append(Categories[test]["erreurCapteur"])

                       if FORET:

                           try:

                               decision = max([(m,[Arbre_Donne_Etat(graphe, racine, ligne) for k, (graphe,racine) in enumerate(self.Foret) if k < NB].count(m)) for m in range(nbCategories)], key=lambda x:x[1])

 
                               dec = decision[0]

                           except:

                               print "Nous devons répéter la {}ème tour de la simulation numéro {} ".format(temps_simulation, nombre_simulation)

                               # Faire un Sleep d'une seconde dans chaque exception
                               sleep(1)

                               for c, cc in self.dicoCapteurs.items() :
                                   cc.energie = EnergieCapteur[c]
                                   cc.mort = MortCapteur[c]
                                   cc.capteursDetectentPanne = CapteursDetectentPanne[c]
                                   if Topologie == 2:
                                       cc.memoire = MemoireC[c]

                               for a, aa in enumerate(self.agregateurs):
                                   aa.energie = EnergieAgregateur[a]   
                                   aa.mort = MortAgregateur[a]
                                   aa.aTransferer = Transferer[a] 
                                   aa.memoire = MemoireA[a]
                       
                               self.valeursRecues = []
                  
                               EnergieCapteur = [] 
                               MortCapteur = []
                               CapteursDetectentPanne = []
                               MemoireC = []
                               EnergieAgregateur = [] 
                               MortAgregateur = []
                               Transferer = []
                               MemoireA = []

                               heure = h

                               continue
   
                           print "Voici la décision par forêt aléatoire sur les données captées {} : ".format(decision)

                           # Ajoute la décision de forêt
                           Decision_Foret.append(dec)
                           
                           
                           Decision_F.append(dec)
                             
                                                      
                           # Ajoute la décision réel
                           decisionreel = Quelle_Categorie(ligne)                       
                           Decision_Reel_Foret.append(decisionreel)
                         
                           Decision_R_F.append(decisionreel)
                                                     

                       if SVM:

                           li = {}

                           for i,j in ligne.items():

                               li[i] = [max(ligne[i])]
                       
                           # Ajoute la décision réel
                           decisionreel = Quelle_Categorie(li) 
                           Decision_Reel_SVM.append(decisionreel)
                          
                           Decision_R_V.append(decisionreel)
                           
                              

                           # Ajoute la décision de SVM
                           tsvm = []

                           for i, j in li.items():
                               tsvm.append(j[0])
                         
                           v = self.Svm.predict(tsvm)
                           dec = v[0]

                           Decision_SVM.append(dec)

                           
                           Decision_S.append(dec)
                         

                           print "Voici la décision par SVM sur les données captées {} : ".format(dec)
    
                       if SGD:

                           li = {}

                           for i,j in ligne.items():
 
                               li[i] = [max(ligne[i])]

                           # Ajoute la décision réel
                           decisionreel = Quelle_Categorie(li) 
                           Decision_Reel_SGD.append(decisionreel)
                          
                           Decision_R_G.append(decisionreel)

                           # Ajoute la décision de SGD
                           tsgd = []

                           for i, j in li.items():
                               tsgd.append(j[0])
                           
                           g = self.Sgd.predict(tsgd)
                           dec = g[0] 
 
                           Decision_SGD.append(dec)

                           Decision_G.append(dec)
                           
                           print "Voici la décision par SGD sur les données captées {} : ".format(dec)

                       if GNB:
                       
                           li = {}

                           for i,j in ligne.items():
 
                               li[i] = [max(ligne[i])]

                           # Ajoute la décision réel
                           decisionreel = Quelle_Categorie(li) 
                           Decision_Reel_GNB.append(decisionreel)
                         
                           Decision_R_N.append(decisionreel)

                           # Ajoute la décision de GNB
                           tgnb = []

                           for i, j in li.items():
                               tgnb.append(j[0])
                           
                           n = self.Gnb.predict(tgnb)
                           dec = n[0] 
 
                           Decision_GNB.append(dec)

                           Decision_N.append(dec)
                           
                           print "Voici la décision par GNB sur les données captées {} : ".format(dec)

                       if TBFS:
                      
                           li = {}

                           for i,j in ligne.items():
 
                               li[i] = [max(ligne[i])]

                           # Ajoute la décision réel
                           decisionreel = Quelle_Categorie(li) 
                           Decision_Reel_TBFS.append(decisionreel)
                         
                           Decision_R_T.append(decisionreel)

                           # Ajoute la décision de TBFS
                           ttbfs = []

                           for i, j in li.items():
                               ttbfs.append(j[0])
                           
                           t = self.Tbfs.predict(ttbfs)
                           dec = t[0] 
 
                           Decision_TBFS.append(dec)

                           Decision_T.append(dec)
                           
                           print "Voici la décision par TBFS sur les données captées {} : ".format(dec) 
                         
                       if MMA:
                       
                           li = {}

                           for i,j in ligne.items():
 
                               li[i] = [max(ligne[i])]

                           # Ajoute la décision réel
                           decisionreel = Quelle_Categorie(li) 
                           Decision_Reel_MMA.append(decisionreel)
                         
                           Decision_R_M.append(decisionreel)

                           # Ajoute la décision de MMA
                           tmma = []

                           for i, j in li.items():
                               tmma.append(j[0])
                           
                           m = self.Mma.predict(tmma)
                           dec = m[0] 
 
                           Decision_MMA.append(dec)

                           Decision_M.append(dec)
                           
                           print "Voici la décision par MMA sur les données captées {} : ".format(dec) 
                          
                       
                       EnergieCapteur = [] 
                       MortCapteur = []
                       CapteursDetectentPanne = []
                       MemoireC = []
                       EnergieAgregateur = [] 
                       MortAgregateur = []
                       Transferer = []
                       MemoireA = []

                   

                       if Topologie == 1:
                           Trace_Topologie_Decision_1(self, str(nombre_simulation)+"_"+str(temps_simulation), dec)
                       elif Topologie == 2:
                           Trace_Topologie_Decision_2(self, str(nombre_simulation)+"_"+str(temps_simulation), dec)                    
                   
              

                       # Le puits récupère les valeurs reçues pour traitement (déchiffrement, si besoin est)
                       while self.valeursRecues != []:
                           valeur = self.valeursRecues[0]
                           self.valeursRecues = self.valeursRecues[1:]
                           if CHIFFREMENT:
                               decr = rsa.decrypt(str(valeur), self.Ks)
                               if Topologie == 1:
                                   self.valeurs.append(int(decr)//MemoireAgregateurs)
                   
                               elif Topologie == 2:
                                   self.valeurs.append(int(decr))     
                           else:
                               if Topologie == 1: 
                                   self.valeurs.append((valeur[0], int(eval(valeur[2])//MemoireAgregateurs)))

                               elif Topologie == 2:
                                   self.valeurs.append((valeur[0], int(eval(valeur[2]))))   
        
           
                       temps_simulation += 1

          
               
               
         
               if FORET:

                   TPf = 0
                   TNf = 0
                   FPf = 0
                   FNf = 0

                   N = TEMPS_SIMULATION*NOMBRE_SIMULATION

                   for i, j in  enumerate(Decision_R_F):
                       if j == 1 and Decision_F[i] == 1 :
                           TPf += 1
                   for x, y in enumerate(Decision_R_F):
                       if y == 0 and Decision_F[x] == 0:
                           TNf += 1 
                   for h, l in  enumerate(Decision_R_F):
                       if l == 0 and Decision_F[h] == 1:
                           FPf += 1
                   for m, n in  enumerate(Decision_R_F):
                       if n == 1 and Decision_F[m] == 0:
                           FNf += 1

                   Acc = float(TPf + TNf) / N
                   Err = float(FNf + FPf) / N

                   TPf = 0
                   TNf = 0
                   FPf = 0
                   FNf = 0

                   Decision_R_F = []
                   Decision_F = []

                   Accuracy_Foret.append(Acc)
                   Erreur_Foret.append(Err)

               if SVM :

                   TPs = 0
                   TNs = 0
                   FPs = 0
                   FNs = 0

                   N = TEMPS_SIMULATION*NOMBRE_SIMULATION

                   for i, j in  enumerate(Decision_R_V):
                       if j == 1 and Decision_S[i] == 1 :
                           TPs += 1
                   for x, y in enumerate(Decision_R_V):
                       if y == 0 and Decision_S[x] == 0:
                           TNs += 1 
                   for h, l in  enumerate(Decision_R_V):
                       if l == 0 and Decision_S[h] == 1:
                           FPs += 1
                   for m, n in  enumerate(Decision_R_V):
                       if n == 1 and Decision_S[m] == 0:
                           FNs += 1

                   Acc = float(TPs + TNs) / N
                   Err = float(FNs + FPs) / N                  
                   
                   TPs = 0
                   TNs = 0
                   FPs = 0
                   FNs = 0

                   Decision_R_V = []
                   Decision_S = []
                 

                   Accuracy_SVM.append(Acc)
                   Erreur_SVM.append(Err)
                   
               if SGD:
       
                   TPg = 0
                   TNg = 0
                   FPg = 0
                   FNg = 0

                   N = TEMPS_SIMULATION*NOMBRE_SIMULATION
  
                   for i, j in  enumerate(Decision_R_G):
                       if j == 1 and Decision_G[i] == 1 :
                           TPg += 1
                   for x, y in enumerate(Decision_R_G):
                       if y == 0 and Decision_G[x] == 0:
                           TNg += 1 
                   for h, l in  enumerate(Decision_R_G):
                       if l == 0 and Decision_G[h] == 1:
                           FPg += 1
                   for m, n in  enumerate(Decision_R_G):
                       if n == 1 and Decision_G[m] == 0:
                           FNg += 1

                   Acc = float(TPg + TNg) / N
                   Err = float(FNg + FPg) / N  
  
                   TPg = 0
                   TNg = 0
                   FPg = 0
                   FNg = 0

                   Decision_R_G = []
                   Decision_G = []

                   Accuracy_SGD.append(Acc)
                   Erreur_SGD.append(Err)

               if GNB:
       
                   TPn = 0
                   TNn = 0
                   FPn = 0
                   FNn = 0

                   N = TEMPS_SIMULATION*NOMBRE_SIMULATION
  
                   for i, j in  enumerate(Decision_R_N):
                       if j == 1 and Decision_N[i] == 1 :
                           TPn += 1
                   for x, y in enumerate(Decision_R_N):
                       if y == 0 and Decision_N[x] == 0:
                           TNn += 1 
                   for h, l in  enumerate(Decision_R_N):
                       if l == 0 and Decision_N[h] == 1:
                           FPn += 1
                   for m, n in  enumerate(Decision_R_N):
                       if n == 1 and Decision_N[m] == 0:
                           FNn += 1

                   Acc = float(TPn + TNn) / N
                   Err = float(FNn + FPn) / N  
  
                   TPn = 0
                   TNn = 0
                   FPn = 0
                   FNn = 0

                   Decision_R_N = []
                   Decision_N = []

                   Accuracy_GNB.append(Acc)
                   Erreur_GNB.append(Err)   

               if TBFS:
               
                   TPt = 0
                   TNt = 0
                   FPt = 0
                   FNt = 0

                   N = TEMPS_SIMULATION*NOMBRE_SIMULATION
  
                   for i, j in  enumerate(Decision_R_T):
                       if j == 1 and Decision_T[i] == 1 :
                           TPt += 1
                   for x, y in enumerate(Decision_R_T):
                       if y == 0 and Decision_T[x] == 0:
                           TNt += 1 
                   for h, l in  enumerate(Decision_R_T):
                       if l == 0 and Decision_T[h] == 1:
                           FPt += 1
                   for m, n in  enumerate(Decision_R_T):
                       if n == 1 and Decision_T[m] == 0:
                           FNt += 1

                   Acc = float(TPt + TNt) / N
                   Err = float(FNt + FPt) / N  
  
                   TPt = 0
                   TNt = 0
                   FPt = 0
                   FNt = 0

                   Decision_R_T = []
                   Decision_T = []

                   Accuracy_TBFS.append(Acc)
                   Erreur_TBFS.append(Err) 
                         
               if MMA:
      
                   TPm = 0
                   TNm = 0
                   FPm = 0
                   FNm = 0

                   N = TEMPS_SIMULATION*NOMBRE_SIMULATION
  
                   for i, j in  enumerate(Decision_R_M):
                       if j == 1 and Decision_M[i] == 1 :
                           TPm += 1
                   for x, y in enumerate(Decision_R_M):
                       if y == 0 and Decision_M[x] == 0:
                           TNm += 1 
                   for h, l in  enumerate(Decision_R_M):
                       if l == 0 and Decision_M[h] == 1:
                           FPm += 1
                   for m, n in  enumerate(Decision_R_M):
                       if n == 1 and Decision_M[m] == 0:
                           FNm += 1

                   Acc = float(TPm + TNm) / N
                   Err = float(FNm + FPm) / N  
  
                   TPm = 0
                   TNm = 0
                   FPm = 0
                   FNm = 0

                   Decision_R_M = []
                   Decision_M = []

                   Accuracy_MMA.append(Acc)
                   Erreur_MMA.append(Err) 

           self.valeurs=self.valeurs[ :300]  
           
           # Production de diverses informations (il faut faire le ménage dedans)
           if len(self.valeurs) != 0:
               print("Moyenne au puits = "+str(float(sum([k[1] for k in self.valeurs]))/len(self.valeurs)))

           print("Nombre de valeurs déchiffrées par le puits : "+str(len(self.valeurs)))
      
           print('self.valeurs'+str(self.valeurs))

           if Topologie == 1:
               # On détermine le nombre de capteurs par agrégateur
               repartition = []
               for ag in self.agregateurs:
                   repartition.append((ag.numero,len(ag.capteurs)))
               print("Répartition des capteurs par agrégateur : "+str(repartition))

           if FORET:

               print  "Decision_Foret est : " + str(Decision_Foret) + "--" + "Decision_reel est : " + str(Decision_Reel_Foret)

               print str(Comparer_Des_Decision(Decision_Reel_Foret, Decision_Foret)) + " décision égaux par rapport à " + str(len(F)*TEMPS_SIMULATION*NOMBRE_SIMULATION) + " décision "
              # On met seulement les décision à une nombre des arbres = 100

               Decision_Reel_Foret = Decision_Reel_Foret[(len(F)-1)*(TEMPS_SIMULATION*NOMBRE_SIMULATION):]
               Decision_Foret =  Decision_Foret[(len(F)-1)*(TEMPS_SIMULATION*NOMBRE_SIMULATION):]

               print "-> On trace deux courbe, la décision des forêts aléatoires et la décision réelle "
               Courbe_Foret(Decision_Reel_Foret, Decision_Foret)
              
               print "-> On trace la courbe d'Accuracy entre la décision des forêts aléatoires et la décision réelle"
               Accuracy_Curve_Foret(F, Accuracy_Foret)

               print "-> On trace la courbe de taux d'erreurs entre la décision des forêts aléatoires et la décision réelle "
               Rate_Curve_Foret(F, Erreur_Foret)
               
           if SVM:

                 print  "Decision_SVM est : " + str(Decision_SVM) + "--" + "Decision_reel est : " + str(Decision_Reel_SVM)     

                 print str(Comparer_Des_Decision(Decision_Reel_SVM, Decision_SVM)) + " décision égaux par rapport à " + str(len(F)*TEMPS_SIMULATION*NOMBRE_SIMULATION) + " décision"

                 Decision_Reel_SVM = Decision_Reel_SVM[(len(F)-1)*(TEMPS_SIMULATION*NOMBRE_SIMULATION):]
                 Decision_SVM = Decision_SVM[(len(F)-1)*(TEMPS_SIMULATION*NOMBRE_SIMULATION):]

                 print "-> On trace deux courbe, la décision des SVM et la décision réelle "
                 Courbe_SVM(Decision_Reel_SVM, Decision_SVM)
                
                 print "-> On trace la courbe d'Accuracy entre la décision de SVM et la décision réelle"
                 Accuracy_Curve_SVM(F, Accuracy_SVM)

                 print "-> On trace la courbe de taux d'erreurs entre la décision de SVM et la décision réelle "
                 Rate_Curve_SVM(F, Erreur_SVM)
                    
           if SGD:
      
               print  "Decision_SGD est : " + str(Decision_SGD) + "--" + "Decision_reel est : " + str(Decision_Reel_SGD)
           
               print str(Comparer_Des_Decision(Decision_Reel_SGD, Decision_SGD)) + " décision égaux par rapport à " + str(len(F)*TEMPS_SIMULATION*NOMBRE_SIMULATION) + " décision"

               Decision_Reel_SGD = Decision_Reel_SGD[(len(F)-1)*(TEMPS_SIMULATION*NOMBRE_SIMULATION):]
               Decision_SGD = Decision_SGD[(len(F)-1)*(TEMPS_SIMULATION*NOMBRE_SIMULATION):]

               print "-> On trace deux courbe, la décision de SGD et la décision réelle "
               Courbe_SGD(Decision_Reel_SGD, Decision_SGD)
         
               print "-> On trace la courbe d'Accuracy entre la décision de SGD et la décision réelle" 
               Accuracy_Curve_SGD(F, Accuracy_SGD)
    
               print "-> On trace la courbe de taux d'erreurs entre la décision de SGD et la décision réelle "
               Rate_Curve_SGD(F, Erreur_SGD)
            
           if GNB:

               print  "Decision_GNB est : " + str(Decision_GNB) + "--" + "Decision_reel est : " + str(Decision_Reel_GNB)
                
               print str(Comparer_Des_Decision(Decision_Reel_GNB, Decision_GNB)) + " décision égaux par rapport à " + str(len(F)*TEMPS_SIMULATION*NOMBRE_SIMULATION) + " décision"
               Decision_Reel_GNB = Decision_Reel_GNB[(len(F)-1)*(TEMPS_SIMULATION*NOMBRE_SIMULATION):]
               Decision_GNB = Decision_GNB[(len(F)-1)*(TEMPS_SIMULATION*NOMBRE_SIMULATION):]
            
               print "-> On trace deux courbe, la décision de GNB et la décision réelle "
               Courbe_GNB(Decision_Reel_GNB, Decision_GNB)
         
               print "-> On trace la courbe d'Accuracy entre la décision de GNB et la décision réelle" 
               Accuracy_Curve_GNB(F, Accuracy_GNB)
    
               print "-> On trace la courbe de taux d'erreurs entre la décision de GNB et la décision réelle "
               Rate_Curve_GNB(F, Erreur_GNB)

           if TBFS:  
           
               print  "Decision_TBFS est : " + str(Decision_TBFS) + "--" + "Decision_reel est : " + str(Decision_Reel_TBFS)
                
               print str(Comparer_Des_Decision(Decision_Reel_TBFS, Decision_TBFS)) + " décision égaux par rapport à " + str(len(F)*TEMPS_SIMULATION*NOMBRE_SIMULATION) + " décision"
               Decision_Reel_TBFS = Decision_Reel_TBFS[(len(F)-1)*(TEMPS_SIMULATION*NOMBRE_SIMULATION):]
               Decision_TBFS = Decision_TBFS[(len(F)-1)*(TEMPS_SIMULATION*NOMBRE_SIMULATION):]

               print "-> On trace deux courbe, la décision de TBFS et la décision réelle "
               Courbe_TBFS(Decision_Reel_TBFS, Decision_TBFS)
         
               print "-> On trace la courbe d'Accuracy entre la décision de TBFS et la décision réelle" 
               Accuracy_Curve_TBFS(F, Accuracy_TBFS)
    
               print "-> On trace la courbe de taux d'erreurs entre la décision de TBFS et la décision réelle "
               Rate_Curve_TBFS(F, Erreur_TBFS)

           if MMA:

               print  "Decision_MMA est : " + str(Decision_MMA) + "--" + "Decision_reel est : " + str(Decision_Reel_MMA)
                
               print str(Comparer_Des_Decision(Decision_Reel_MMA, Decision_MMA)) + " décision égaux par rapport à " + str(len(F)*TEMPS_SIMULATION*NOMBRE_SIMULATION) + " décision"
               Decision_Reel_MMA = Decision_Reel_MMA[(len(F)-1)*(TEMPS_SIMULATION*NOMBRE_SIMULATION):]
               Decision_MMA = Decision_MMA[(len(F)-1)*(TEMPS_SIMULATION*NOMBRE_SIMULATION):]

               print "-> On trace deux courbe, la décision de MMA et la décision réelle "
               Courbe_MMA(Decision_Reel_MMA, Decision_MMA)
         
               print "-> On trace la courbe d'Accuracy entre la décision de MMA et la décision réelle" 
               Accuracy_Curve_MMA(F, Accuracy_MMA)
    
               print "-> On trace la courbe de taux d'erreurs entre la décision de MMA et la décision réelle "
               Rate_Curve_MMA(F, Erreur_MMA)
  
           print "-> On trace l'évolution de la topologie, dans filmTopologie.avi"
           Film_Topologie()


           # On trace les films de ce qui s'est produit...
           print "-> On trace ce qui se passe au puits, dans videoPuits.avi"

           if Topologie == 1:
               Trace_Valeurs_Puits_1(self)
           elif Topologie == 2:
               Trace_Valeurs_Puits_2(self)

       
           # Fin de la simulation
           print("On stoppe tout le monde") 
       
       
       elif SIR :

           print "Tu choisie SIR model"
           sleep(1)

           global Presence_Puits
           global Nombre_Capteur_Diffuse

           Test_Presence_Puits = Presence_Puits
           Test_Nombre_Capteur_Diffuse = Nombre_Capteur_Diffuse

           Temps_Arrive_puits = {}
           Nombre_Voisin_Intrusion = {}
           Nombre_Voisin_Vie = {}

           for Presence_Puits in [10, 20, 40, 60, 80, 100] :

               print "Simulation avec {} secondes pour le puits est arrive ".format(Presence_Puits) 
               # Faire un Sleep d'une seconde dans chaque boucle
               sleep(1)
               
               for cc in self.dicoCapteurs.values() :
                   cc.energie = BatterieCapteurs
                   cc.mort = False                 
                   cc.memoire = []

               self.valeursRecues = []
  
               for i in range(NOMBRE_SIR) :
             
                   print "C'est le {}ème SIMULATION ".format(i)

                   for temps in range(Presence_Puits):

                       print "    -> Capteurs restants :", len([c for c in self.dicoCapteurs.values() if not c.mort])
                       print("Durée écoulée : " + str(temps) + " secondes")
             
                       for cpt in self.dicoCapteurs.values() :
                           if not cpt.mort:
                           # Les capteurs ont leur énergie qui décroit naturellement 
                               cpt.energie -= coutEcouteCapteurs
                               if cpt.energie < 0:
                                   cpt.mort = True
                     
                               else:
                                   # capte si il y a une intrusion ou non
                                   cpt.valeur = randint(0, 10)

                                   cpt.memoire.append(cpt.valeur)

                                   if temps == Taux_Diffusion  and cpt.memoire.count(1) != 0 :
                                       # envoie les donnees aux voisins
                                       voisin = Voisin(self, cpt)

                                       k = 0 
                                       n = 0 

                                       while n < Nombre_Capteur_Diffuse:

                                           if not voisin[k].mort :
                                               # On décrémente l'énergie du capteur du coût de transmission à leur voisin
                                               cpt.energie -= Energie_Capteur(capteur = cpt, cible = voisin[k], indice = 2)

                                               if cpt.energie > 0 :
                                    
                                                   voisin[k].memoire.extend(cpt.memoire)
                                                   n += 1
                                               else :
                                    
                                                   cpt.mort = True
                                                   break
                                        

                                           k += 1

                                           if k == len(voisin):
                                               break 

                 
                   # La puits est arrivé
                   # envoie les donnees capte par capteur au puits

                   print "La puits est arrivé"               

                   for cpt in self.dicoCapteurs.values() :

                       if not cpt.mort: 
                           # On décrémente l'énergie du capteur du coût de transmission à la puits
                           cpt.energie -= Energie_Capteur(capteur = cpt, cible = self, indice = 2)

                           if cpt.energie > 0 :
                               self.valeursRecues.extend(cpt.memoire) 
                               cpt.memoire = []    
                 
                           else :
                               cpt.mort = True

                   print " --> Capteurs restants :", len([c for c in self.dicoCapteurs.values() if not c.mort])
   

                   Trace_Topologie_2(self, str(Presence_Puits) + str(i).zfill(10))
                
               Temps_Arrive_puits[Presence_Puits] = self.valeursRecues.count(1)


           sp = []
           X = []
           Y = []

           for i, j in  Temps_Arrive_puits.items() :
               sp.append((i,j))  
  
           sp = sorted(sp)
            
           print sp

           for x,y in sp:
               X.append(x)
               Y.append(y)

           Presence_Puits = Test_Presence_Puits
           Courbe_Temps_Puits(X, Y)

         

           # On va étudier les variation de nombre de diffusion par rapport au nombre d'intrusion capter 

           for  Nombre_Capteur_Diffuse in [0, 1, 2, 3, 4, 5] :

               print "Cette simulation possède {} diffusion de chaque capteur à son voisins  ".format(Nombre_Capteur_Diffuse) 

               # Faire un Sleep d'une seconde dans chaque boucle
               sleep(1)
               
               for cc in self.dicoCapteurs.values() :
                   cc.energie = BatterieCapteurs
                   cc.mort = False                 
                   cc.memoire = []

               self.valeursRecues = []
  
               for i in range(NOMBRE_SIR) :
             
                   print "C'est le {}ème SIMULATION ".format(i)

                   for temps in range(Presence_Puits):

                       print "    -> Capteurs restants :", len([c for c in self.dicoCapteurs.values() if not c.mort])
                       print("Durée écoulée : " + str(temps) + " secondes")
                   
                       for cpt in self.dicoCapteurs.values() :
                           if not cpt.mort:
                           # Les capteurs ont leur énergie qui décroit naturellement 
                               cpt.energie -= coutEcouteCapteurs
                               if cpt.energie < 0:
                                   cpt.mort = True
                     
                               else:
                                   # capte si il y a une intrusion ou non
                                   cpt.valeur = randint(0, 10)

                                   cpt.memoire.append(cpt.valeur)

                                   if temps == Taux_Diffusion and cpt.memoire.count(1) != 0 :
                                       # envoie les donnees aux voisins
                                       voisin = Voisin(self, cpt)

                                       k = 0 
                                       n = 0 
                                      
                                       while n < Nombre_Capteur_Diffuse:

                                           if not voisin[k].mort :
                                               # On décrémente l'énergie du capteur du coût de transmission à leur voisin
                                               cpt.energie -= Energie_Capteur(capteur = cpt, cible = voisin[k], indice = 2)

                                               if cpt.energie > 0 :
                                    
                                                   voisin[k].memoire.extend(cpt.memoire)
                                                   n += 1
                                               else :
                                    
                                                   cpt.mort = True
                                                   break
                                        

                                           k += 1

                                           if k == len(voisin):
                                               break 

                 
                   # La puits est arrivé
                   # envoie les donnees capte par capteur au puits

                   print "La puits est arrivé"               

                   for cpt in self.dicoCapteurs.values() :

                       if not cpt.mort: 
                           # On décrémente l'énergie du capteur du coût de transmission à la puits
                           cpt.energie -= Energie_Capteur(capteur = cpt, cible = self, indice = 2)

                           if cpt.energie > 0 :
                               self.valeursRecues.extend(cpt.memoire) 
                               cpt.memoire = []    
                 
                           else :
                               cpt.mort = True

                   print " --> Capteurs restants :", len([c for c in self.dicoCapteurs.values() if not c.mort])
   

                   Trace_Topologie_2(self, str(Nombre_Capteur_Diffuse) + str(i).zfill(10))
                
               Nombre_Voisin_Intrusion[Nombre_Capteur_Diffuse] = self.valeursRecues.count(1)
               
           sp = []
           Z = []
           W = []

           for i, j in  Nombre_Voisin_Intrusion.items() :
               sp.append((i,j))  
  
           sp = sorted(sp)
            
           print sp

           for x,y in sp:
               Z.append(x)
               W.append(y)


           Nombre_Capteur_Diffuse = Test_Nombre_Capteur_Diffuse 
           Courbe_Voisin_Intrusion(Z, W)

           # On va étudier les variation de nombre de diffusion par rapport au durée de la vie d'une reseaux 
 
           for  Nombre_Capteur_Diffuse in [0, 1, 2, 3, 4, 5] :

               print "Cette simulation possède {} diffusion de chaque capteur à son voisins  ".format(Nombre_Capteur_Diffuse) 

               # Faire un Sleep d'une seconde dans chaque boucle
               sleep(1)
               
               for cc in self.dicoCapteurs.values() :
                   cc.energie = BatterieCapteurs
                   cc.mort = False                 
                   cc.memoire = []

               self.valeursRecues = []
               
               t = time()
               tm = 0
               while len([c for c in self.dicoCapteurs.values() if not c.mort]) != 0 :
             

                   for temps in range(Presence_Puits):

                       print "    -> Capteurs restants :", len([c for c in self.dicoCapteurs.values() if not c.mort])
                       print("Durée écoulée : " + str(temps) + " secondes")
                   
                       for cpt in self.dicoCapteurs.values() :
                           if not cpt.mort:
                           # Les capteurs ont leur énergie qui décroit naturellement 
                               cpt.energie -= coutEcouteCapteurs
                               if cpt.energie < 0:
                                   cpt.mort = True
                     
                               else:
                                   # capte si il y a une intrusion ou non
                                   cpt.valeur = randint(0, 10)

                                   cpt.memoire.append(cpt.valeur)

                                   if temps == Taux_Diffusion and cpt.memoire.count(1) != 0 :
                                       # envoie les donnees aux voisins
                                       voisin = Voisin(self, cpt)

                                       k = 0 
                                       n = 0 
                                      
                                       while n < Nombre_Capteur_Diffuse:

                                           if not voisin[k].mort :
                                               # On décrémente l'énergie du capteur du coût de transmission à leur voisin
                                               cpt.energie -= Energie_Capteur(capteur = cpt, cible = voisin[k], indice = 2)

                                               if cpt.energie > 0 :
                                    
                                                   voisin[k].memoire.extend(cpt.memoire)
                                                   n += 1
                                               else :
                                    
                                                   cpt.mort = True
                                                   break
                                        

                                           k += 1

                                           if k == len(voisin):
                                               break 

                 
                   # La puits est arrivé
                   # envoie les donnees capte par capteur au puits

                   print "La puits est arrivé"               

                   for cpt in self.dicoCapteurs.values() :

                       if not cpt.mort: 
                           # On décrémente l'énergie du capteur du coût de transmission à la puits
                           cpt.energie -= Energie_Capteur(capteur = cpt, cible = self, indice = 2)

                           if cpt.energie > 0 :
                               self.valeursRecues.extend(cpt.memoire) 
                               cpt.memoire = []    
                 
                           else :
                               cpt.mort = True

                   print " --> Capteurs restants :", len([c for c in self.dicoCapteurs.values() if not c.mort])
   

                   Trace_Topologie_2(self, str(Nombre_Capteur_Diffuse) + str(tm).zfill(10))

                   tm += 1
               Nombre_Voisin_Vie[Nombre_Capteur_Diffuse] = time() - t
               
           sp = []
           T = []
           H = []

           for i, j in  Nombre_Voisin_Vie.items() :
               sp.append((i, j))  
  
           sp = sorted(sp)
            
           print sp

           for x, y in sp:
               T.append(x)
               H.append(y)


           Nombre_Capteur_Diffuse = Test_Nombre_Capteur_Diffuse 
           Courbe_Voisin_Vie(T, H)
 
 
           
           # Fin de la simulation
           print("On stoppe tout le monde")
  
           
       
